package com.lmaos.allcontrol.modulecontrol.impl;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

import com.lmaos.allcontrol.beancontrol.class_.MyClassLibrary;
import com.lmaos.allcontrol.beancontrol.class_.MyClassLoader;
import com.lmaos.allcontrol.beancontrol.method_.MethodUtils;
import com.lmaos.allcontrol.modulecontrol.ModuleBean;
import com.lmaos.allcontrol.modulecontrol.ModuleLoader;
import com.lmaos.allcontrol.modulecontrol.ModuleLoaderCondition;
import com.lmaos.allcontrol.modulecontrol.ModuleObjectInstance;
import com.lmaos.basetools.files.scan.ScanFile;
import com.lmaos.basetools.files.scan.factory.DirAndJarScanFileFactory;

public class ModuleLoaderDefaultImpl implements ModuleLoader{
	ModuleObjectInstance moduleObjectInstance;
	ModuleLoaderCondition moduleLoaderCondition;
	boolean scanjar = true;
	@Override
	public void setModuleLoaderCondition(
			ModuleLoaderCondition moduleLoaderCondition) {

		this.moduleLoaderCondition = moduleLoaderCondition;
	}

	@Override
	public void setModuleObjectInstance(
			ModuleObjectInstance moduleObjectInstance) {
		this.moduleObjectInstance = moduleObjectInstance;
	}
	MyClassLibrary classLibrary = MyClassLibrary.getClassLibrary();
	@Override
	public List<ModuleBean> loadModule(String classPath, String classInstallName) {
		List<ModuleBean> moduleBeans = new ArrayList<ModuleBean>();
		if(moduleLoaderCondition == null){
			return moduleBeans;
		}
		ClassLoader classLoader = null;
		if(classInstallName==null||classInstallName.isEmpty()){
			classLoader = MyClassLibrary.class.getClassLoader();
		}else{
			classLoader = new MyClassLoader(classPath);
			classLibrary.uninstallAndInstall(classInstallName, classLoader);
		}
		List<ScanFile> scanFiles = null;
		if(scanjar||classPath.endsWith(".jar")){
			scanFiles = DirAndJarScanFileFactory.scan(classPath);
		}else{
			scanFiles = DirAndJarScanFileFactory.scanOnlyDir(classPath);
		}
		for (ScanFile scanFile : scanFiles) {
			String className = scanFile.getClassName();
			if(className!=null&&moduleLoaderCondition.enabled(className,classLoader)){
				try {
					Class clazz = classLoader.loadClass(className);
					List<Method> methods = MethodUtils.getMethods(clazz);
					List<Method> enabledMethods = new ArrayList<Method>();
					for (Method method : methods) {
						if(moduleLoaderCondition.enabled(clazz, method)){
							enabledMethods.add(method);
						}
					}
					if(enabledMethods.size() > 0){
						Object instance = newInstance(clazz);
						ModuleBean moduleBean = new ModuleBean(classInstallName, classPath, clazz, instance, enabledMethods);
						moduleBeans.add(moduleBean);
					}
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}		
		return moduleBeans;
	}
	private Object newInstance(Class clazz){
		if(moduleObjectInstance == null){
			return null;
		}
		try {
			return moduleObjectInstance.newInstance(clazz);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	@Override
	public List<ModuleBean> loadModule(String classPath) {
		if(!classPath.endsWith("/")){
			return new ArrayList<ModuleBean>();
		}
		return loadModule(classPath, null);
	}

	@Override
	public void setScanJar(boolean scanjar) {
		this.scanjar = scanjar;
		
	}

}
